home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_069 / wc / wc.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  390 lines

  1. /*
  2.  *  wc [ -lwcp ] [ -spagesize ] [ -v ] [ files... ]
  3.  *
  4.  *  Count lines, words, characters, and pages.
  5.  *
  6.  *  Runs faster by doing less work if it doesn't have to count
  7.  *  all quantities.
  8.  *
  9.  *  Use this program as you wish, but please leave this header intact.
  10.  *
  11.  *  Steve Summit 12/4/84
  12.  */
  13.  
  14. #include <stdio.h>
  15.  
  16. #ifdef unix
  17. extern char *rindex();
  18. #else
  19. #define rindex strrchr
  20. extern char *strrchr();
  21. #endif
  22. extern char *strcat();
  23. extern char *strcpy();
  24.  
  25. #define TRUE 1
  26. #define FALSE 0
  27.  
  28. long int totchars = 0;
  29. long int totwords = 0;
  30. long int totlines = 0;
  31. long int totpages = 0;
  32.  
  33. #define LINES    04
  34. #define WORDS    02
  35. #define CHARS    01
  36.  
  37. int count = LINES | WORDS | CHARS;
  38. char want[10] = "lwc";
  39.  
  40. int verbose = FALSE;
  41.  
  42. int pagelen = 66;
  43.  
  44. int errs = 0;
  45.  
  46. int deflt = TRUE;
  47.  
  48. #define Isdigit(c) ((c) >= '0' && (c) <= '9')
  49. #define Ctod(c) ((c) - '0')
  50.  
  51. #ifdef unix
  52.  
  53. #define Append(mask, letter)    if(deflt)                \
  54.                     {                \
  55.                     count = mask;            \
  56.                     (void)strcpy(want, letter);    \
  57.                     deflt = FALSE;            \
  58.                     }                \
  59.                 else    {                \
  60.                     count |= mask;            \
  61.                     (void)strcat(want, letter);    \
  62.                     }
  63.  
  64. #define Append2(letter)        if(deflt)                \
  65.                     {                \
  66.                     (void)strcpy(want, letter);    \
  67.                     deflt = FALSE;            \
  68.                     }                \
  69.                 else    (void)strcat(want, letter)
  70.  
  71. #else
  72.  
  73. Append(mask, letter)
  74. {
  75.     if(deflt)
  76.     {
  77.         count = mask;
  78.         (void)strcpy(want, letter);
  79.         deflt = FALSE;
  80.     }
  81.     else
  82.     {
  83.         count |= mask;
  84.         (void)strcat(want, letter);
  85.     }
  86. }
  87.  
  88. Append2(letter)
  89. {
  90.     if(deflt)
  91.     {
  92.         (void)strcpy(want, letter);
  93.         deflt = FALSE;
  94.     }
  95.     else
  96.     {
  97.         (void)strcat(want, letter);
  98.     }
  99. }
  100.  
  101. #endif
  102.  
  103. char *progname = "wc";
  104.  
  105. main(argc, argv)
  106. int argc;
  107. char *argv[];
  108. {
  109. int fd;
  110. int argi;
  111. char *p;
  112. int totals;
  113.  
  114. if(argc > 0)
  115.     {
  116.     p = rindex(argv[0], '/');
  117.     if(p != NULL)
  118.         progname = p + 1;
  119.     else    progname = argv[0];
  120.     }
  121.  
  122. for(argi = 1; argi < argc && argv[argi][0] == '-'; argi++)
  123.     {
  124.     for(p = &argv[argi][1]; *p != '\0'; p++)
  125.         {
  126.         switch(*p)
  127.             {
  128.             case 'l':
  129.                 Append(LINES, "l");
  130.                 break;
  131.  
  132.             case 'w':
  133.                 Append(WORDS, "w");
  134.                 break;
  135.  
  136.             case 'c':
  137.                 Append(CHARS, "c");
  138.                 break;
  139.  
  140.             case 'p':
  141.                 Append2("p");
  142.                 break;
  143.  
  144.             case 'v':
  145.                 verbose = TRUE;
  146.                 if(deflt)
  147.                     (void)strcpy(want, "lwcp");
  148.                 break;
  149.  
  150.             case 's':
  151.                 pagelen = 0;
  152.                 while(Isdigit(*(p + 1)))
  153.                     pagelen = 10 * pagelen + Ctod(*++p);
  154.                 break;
  155.  
  156.             default:
  157.                 fprintf(stderr, "%s: unknown option -%c\n",
  158.                                 progname, *p);
  159.             }
  160.         }
  161.     }
  162.  
  163. if(verbose)
  164.     {
  165.     for(p = want; *p != '\0'; p++)
  166.         {
  167.         switch(*p)
  168.             {
  169.             case 'l':
  170.                 printf("   lines");
  171.                 break;
  172.  
  173.             case 'w':
  174.                 printf("   words");
  175.                 break;
  176.  
  177.             case 'c':
  178.                 printf("   chars");
  179.                 break;
  180.  
  181.             case 'p':
  182.                 printf("   pages");
  183.                 break;
  184.             }
  185.         }
  186.  
  187.     putchar('\n');
  188.     }
  189.  
  190. if(argi >= argc)
  191.     wc("", 0);
  192. else    {
  193.     totals = (argi + 1) < argc;
  194.  
  195.     for(; argi < argc; argi++)
  196.         {
  197.         if((fd = open(argv[argi], 0)) < 0)
  198.             {
  199.             fprintf(stderr, "%s: can't open %s\n", progname,
  200.                                 argv[argi]);
  201.             perror("");
  202.             errs++;
  203.             continue;
  204.             }
  205.         wc(argv[argi], fd);
  206.         (void)close(fd);
  207.         }
  208.  
  209.     if(totals)
  210.         {
  211.         printit(totlines, totwords, totchars, totpages);
  212.         printf(" total\n");
  213.         }
  214.     }
  215.  
  216. exit(errs);
  217. }
  218.  
  219. #define Set(flag)    flag++
  220. #define Clear(flag)    flag = FALSE
  221.  
  222. #define Checkline()    if(*p == '\n')                    \
  223.                 lines++
  224.  
  225. #define Checkword()    if(' ' < *p && *p < '\177')            \
  226.                 {                    \
  227.                 if(!inword)                \
  228.                     {                \
  229.                     words++;            \
  230.                     Set(inword);            \
  231.                     }                \
  232.                 continue;                \
  233.                 }
  234.  
  235. #define Checkword2()    else if(*p != ' ' && *p != '\t')         \
  236.                 continue;                \
  237.             Clear(inword)
  238.  
  239. #define Checkword3()    if(*p == ' ' || *p == '\n' || *p == '\t')    \
  240.                 Clear(inword)
  241.  
  242. #define Dochars()    chars += r
  243.  
  244. wc(name, fd)
  245. char *name;
  246. int fd;
  247. {
  248. char buf[BUFSIZ];
  249. register char *bufend;
  250. int r;
  251. long int lines, words, chars, pages;
  252. register char *p;
  253. register int inword;
  254.  
  255. lines = words = chars = pages = 0;
  256.  
  257. Clear(inword);
  258.  
  259. switch(count)
  260.     {
  261.     case LINES:
  262.         while((r = read(fd, buf, BUFSIZ)) > 0)
  263.             {
  264.             bufend = buf + r;
  265.             for(p = buf; p < bufend; p++)
  266.                 Checkline();
  267.             }
  268.         break;
  269.  
  270.     case WORDS:
  271.         while((r = read(fd, buf, BUFSIZ)) > 0)
  272.             {
  273.             bufend = buf + r;
  274.             for(p = buf; p < bufend; p++)
  275.                 {
  276.                 Checkword();
  277.                 Checkword3();
  278.                 }
  279.             }
  280.         break;
  281.  
  282.     case CHARS:
  283.         while((r = read(fd, buf, BUFSIZ)) > 0)
  284.             Dochars();
  285.         break;
  286.  
  287.     case LINES|CHARS:
  288.         while((r = read(fd, buf, BUFSIZ)) > 0)
  289.             {
  290.             Dochars();
  291.  
  292.             bufend = buf + r;
  293.             for(p = buf; p < bufend; p++)
  294.                 Checkline();
  295.             }
  296.         break;
  297.  
  298.     case LINES|WORDS:
  299.         while((r = read(fd, buf, BUFSIZ)) > 0)
  300.             {
  301.             bufend = buf + r;
  302.             for(p = buf; p < bufend; p++)
  303.                 {
  304.                 Checkword();
  305.                 Checkline();
  306.                 Checkword2();
  307.                 }
  308.             }
  309.         break;
  310.  
  311.     case WORDS|CHARS:
  312.         while((r = read(fd, buf, BUFSIZ)) > 0)
  313.             {
  314.             Dochars();
  315.  
  316.             bufend = buf + r;
  317.             for(p = buf; p < bufend; p++)
  318.                 {
  319.                 Checkword();
  320.                 Checkword3();
  321.                 }
  322.             }
  323.         break;
  324.  
  325.     case LINES|WORDS|CHARS:
  326.         while((r = read(fd, buf, BUFSIZ)) > 0)
  327.             {
  328.             Dochars();
  329.  
  330.             bufend = buf + r;
  331.             for(p = buf; p < bufend; p++)
  332.                 {
  333.                 Checkword();
  334.                 Checkline();
  335.                 Checkword2();
  336.                 }
  337.             }
  338.         break;
  339.     }
  340.  
  341. if(r < 0)
  342.     {
  343.     fprintf(stderr, "%s: %s: read error\n", progname,
  344.                 *name != '\0' ? name : "standard input");
  345.     perror("");
  346.     errs++;
  347.     }
  348.  
  349. pages = lines / pagelen + (lines % pagelen != 0 ? 1 : 0);
  350.  
  351. printit(lines, words, chars, pages);
  352.  
  353. if(*name != '\0')
  354.     printf(" %s", name);
  355. putchar('\n');
  356.  
  357. totlines += lines;
  358. totwords += words;
  359. totchars += chars;
  360. totpages += pages;
  361. }
  362.  
  363. printit(lines, words, chars, pages)
  364. long int lines, words, chars, pages;
  365. {
  366. char *p;
  367.  
  368. for(p = want; *p != '\0'; p++)
  369.     {
  370.     switch(*p)
  371.         {
  372.         case 'l':
  373.             printf(" %7ld", lines);
  374.             break;
  375.  
  376.         case 'w':
  377.             printf(" %7ld", words);
  378.             break;
  379.  
  380.         case 'c':
  381.             printf(" %7ld", chars);
  382.             break;
  383.  
  384.         case 'p':
  385.             printf(" %7ld", pages);
  386.             break;
  387.         }
  388.     }
  389. }
  390.